import { styled, createGlobalStyle, css } from "styled-components";
import { useEffect, useMemo, useRef } from "react";
import "./index.scss";

export default function index() {
	const keys: Record<string, { frequency: number }> = {
		A: {
			frequency: 196,
		},
		S: {
			frequency: 220,
		},
		D: {
			frequency: 246,
		},
		F: {
			frequency: 261,
		},
		G: {
			frequency: 293,
		},
		H: {
			frequency: 329,
		},
		J: {
			frequency: 349,
		},
		K: {
			frequency: 392,
		},
	};

	// 创建实例
	const context = useMemo(() => {
		return new AudioContext();
	}, []);

	// 用来存储当前的音频播放状态
	const currentOscillator = useRef<OscillatorNode | null>(null);

	// 用来存储所有setTimeout的ID
	const timeouts = useRef<number[]>([]);

	// 停止当前播放的oscillator
	const stopCurrentOscillator = () => {
		if (currentOscillator.current) {
			currentOscillator.current.stop();
			currentOscillator.current = null;
		}
	};

	// 清除所有排队的 setTimeout
	const clearAllTimeouts = () => {
		timeouts.current.forEach((timeoutId) => clearTimeout(timeoutId));
		timeouts.current = [];
	};

	const play = (key: string) => {
		const frequency = keys[key]?.frequency;
		if (!frequency) {
			return;
		}
		// 停止之前的音频
		stopCurrentOscillator();

		const osc = context.createOscillator();
		osc.type = "sine";
		osc.frequency.value = frequency;

		const gain = context.createGain();
		osc.connect(gain);
		gain.connect(context.destination);

		gain.gain.setValueAtTime(0, context.currentTime);
		gain.gain.linearRampToValueAtTime(1, context.currentTime + 0.01);

		osc.start(context.currentTime);

		gain.gain.exponentialRampToValueAtTime(0.001, context.currentTime + 1);
		osc.stop(context.currentTime + 1);

		// 设置当前的oscillator
		currentOscillator.current = osc;

		document.getElementById(`key-${key}`)?.classList.add("pressed");
		setTimeout(() => {
			document.getElementById(`key-${key}`)?.classList.remove("pressed");
		}, 100);
	};

	useEffect(() => {
		document.addEventListener("keydown", (e) => {
			play(e.key.toUpperCase());
		});
	}, []);

	const map: Record<number, string> = {
		1: "A",
		2: "S",
		3: "D",
		4: "F",
		5: "G",
		6: "H",
		7: "J",
		8: "K",
	};

	const playMusic = (music: number[][]) => {
		let startTime = 0;

		// 停止上一段音乐
		stopCurrentOscillator();
		// 清除所有排队的音符
		clearAllTimeouts();

		music.forEach((item) => {
            const [note , duration] = item
            if(note === 0){
                // 如果遇到 0，则只是停顿，不播放任何音符
                const timeoutId = setTimeout(() => {
                    // 不做任何事情，只是等待
                }, startTime * 0.5);
                // @ts-ignore
                timeouts.current.push(timeoutId);
            }else{
                const timeoutId = setTimeout(() => {
                    play(map[item[0]]);
                }, startTime * 0.5);
                // 记录当前的 setTimeout ID
                // @ts-ignore
                timeouts.current.push(timeoutId);
                
            }
			startTime += duration;
		});
	};

	const GlobalStyles = createGlobalStyle`
    .pressed {
        background: #aaa;
    }`;

	const KeysStyle = styled.div`
		margin: 40px auto;

		display: flex;
		flex-direction: row;
		justify-content: space-between;
		overflow: hidden;
	`;
	const textStyle = css`
		line-height: 30vw;
		text-align: center;
		font-size: 24px;
	`;

	const KeyStyle = styled.div`
		border: 2px solid black;
		background: #fff;
		flex: 1;
		${textStyle}
        height: 30vw;
        border-radius: 6px;
		&:hover {
			background: #aaa;
		}
	`;

	const playSong1 = () => {
		const music = [
			[6, 1000],
			[5, 1000],
			[3, 1000],
			[5, 1000],
			[8, 1000],
			[6, 500],
			[5, 500],
			[6, 1000],
		];
		playMusic(music);
	};

	const playSong2 = () => {
		const music = [
			[6, 1000],
			[6, 1000],
			[6, 1000],
			[3, 500],
			[6, 500],
			[5, 1000],
			[3, 500],
			[2, 500],
			[3, 1000],
		];
		playMusic(music);
	};

	const playSecret = () => {
		const music = [
			// 最美不是的下雨天
			[5, 1000], // la
			[4, 800], // sol
			[4, 1200], // mi
			[4, 1000], // do
			[4, 1000], // re
			[3, 1000], // mi
			[3, 1200], // sol (hold)

            [0,1200],

			// 是曾与你躲过雨的屋檐
			[4, 700], // la 是
            [4, 700], // la 曾
			[4, 800], // sol 与你
            [5, 1000], // sol 与你
			[3, 800], // mi  躲过
			[2, 800], // do
            [1, 1200], // do
			[7, 1000], // re  屋檐
            [7, 800], // re  屋檐
			[2, 1200], // mi
			[1, 4000], // re (hold)
		];

		playMusic(music);
	};

	return (
		<div>
			<KeysStyle as="div">
				{Object.keys(keys).map((item: any) => {
					return (
						<KeyStyle as="div" key={item}>
							<div onClick={() => play(item)} id={`key-${item}`}>
								<span>{item}</span>
							</div>
						</KeyStyle>
					);
				})}
				<GlobalStyles />
			</KeysStyle>
			<div className="songs">
				<button onClick={() => playSong1()}>世上只有妈妈好</button>
				<button onClick={() => playSong2()}>奢香夫人</button>
				<button onClick={() => playSecret()}>不能说的秘密</button>
			</div>
		</div>
	);
}
